// ts 默认我们声明的类型都在全局上, 我们可以通过模块化规范来进行隔离
// ts特性： ts本身就是给js添加类型 学习ts中的类型（先掌握内置类型，在掌握自定义类型，ts中还有高级类型） 什么时候我们需要写类型

// 如果不指定类型，我们ts会根据赋予的值添加类型, 如果没有赋值默认类型就是any

// ts 会根据等号右边的内容推到他自身的类型，没有类型就是any , 在ts中:后面跟着的都是类型
// any会导致类型检测失效，能不写any 就不要写any

// 1.ts中的基础类型  如果用大写的类型 String /Number / Boolean 类， 类也可以充当类型  类类型
// 大写的类型用来描述实例的
// 字符串 数字 number
let str: string = "zf";
let age: number = 100;
let bool: boolean = true;

let str0: string = "zf";
let str1: String = "zf"; // 字符串也是String的一个实例，调用方法的时候会进行装箱
// 把简单类型转换成引用类型 是装箱  'zf' -> new String('zf')
// let str2: String = new String("xxx");
// let str3: string = new String("xxx"); // 我们将一个对象标识成了基本数据类型
// export {}; // 导出后这个变量就属于模块内了，不会被声明在全局上

// 2.数组 什么叫数组，存放一类类型的集合
// 标识数组的类型
let arr: (string | number)[] = []; // any[] 表示的是数组里可以放任何类型， any 表示啥都行， 如果数组里存放多个类型可以采用联合类型
arr.push(100);
// arr.push(true);

let item = arr[0]; // 联合类型无法调用具体的方法，只能调用公共的方法  ts重要特性是为了安全发明的

// 3.可以通过泛型来约束数组
let arr1: Array<number | string> = []; // 泛型...  当使用这个类型的时候才能确定是什么类型

// 3.在ts中还新增了一种类型 元组 长度类型都是固定的
let tuple: [string, number, boolean] = ["zf", 13, true];
// 元组是可以通过调用数组方法来添加数据的但是要求是必须在这些类型中
tuple.push(123); // 特殊的

// 4. 默认枚举类型会被编译成对象
// 源码里面表示不同状况的参数
enum AUTH { // 状态码，请求路径 常量 , 可以放置混合类型，但是只有数字后面才能递增
  ADMIN,
  MANGAER = 3,
  USER,
  // ADMIN = 'admin',
  // MANGAER = 'manager',
  // USER = 'user'
}
console.log(AUTH.ADMIN);
// 常量枚举 最终编译后的结果会变成具体的结果， 只要不是数组都不能反举。

console.log(Object.keys(AUTH).length);

// 5. null undefined
// ts 中的null和undefined可以赋值给任何类型  , 一般在开发的时候尽量严格模式都是开启状态
let un: undefined = undefined;
let nu: null = null;

// 6.void表示返回值为空, 在非严格模式下 null可以赋予给任何类型， undefine是可以兼容void的
function sum(): void {
  return undefined;
}
// 类型无法和值运算

// 7.never 永远达不到的情况  3中情况会出现never  1） 程序出错走不到了 2）死循环  3） 条件永远走不到
function whileTrue(): never {
  while (true) {}
}
function throwError(): never {
  throw new Error();
}
function isType(str: string) {
  if (typeof str === "string") {
  } else {
    str; // 永远总不到就是never
  }
}
let s: symbol = Symbol();
let b: bigint = BigInt(Number.MAX_SAFE_INTEGER) + BigInt(1);


function create(o:object){ // 不是基本类型的全部用object用来标识

}
create({})
create([])
create(function(){})

// Symol bigInt

// interface ICiclr {
//   kind: "c";
//   r: number;
// }
// interface ISquare {
//   kind: "s";
//   width: number;
// }
// function asset(obj: never) {}  他是来校验的
// function getArea(val: ICiclr | ISquare) {
//   // ts 为了考虑安全
//   if (val.kind === "c") {
//     return val.r * val.r;
//   }
//   if (val.kind === "s") {
//     return val.width * val.width;
//   }
//   asset(val); // 可以用never 来标识永远不会发生的事情
// }

export {};

// 1.:后面跟的都是类型  2. ts学习时候要时刻思考安全问题  3.ts写完后无法直接运行，需要编译成js语法才能使用（写的类型最后编译完后就是一堆空气）
